﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Data.Linq.SqlClient;
using DataLayer.dbml;
using System.Data;
using DataLayer.Utilities;

namespace DataLayer.Controller
{
    /// <summary>
    /// Clase responsable del manejo de los casos
    /// </summary>
    public class CaseController : GenericController<CASO, DataClassesDataContext>
    {

        
        /// <summary>
        /// Creación caso desde SF
        /// </summary>
        /// <param name="idCasoSFDC"></param>
        /// <param name="idCaso"></param>
        /// <param name="tipoCaso"></param>
        /// <param name="motivoCaso"></param>
        /// <param name="problemaEncontrado"></param>
        /// <param name="estadoCaso"></param>
        /// <param name="fechaHoraapertura"></param>
        /// <param name="fechaHoraCierre"></param>
        /// <param name="descripcion"></param>
        /// <param name="tiempoCasoabierto"></param>
        /// <param name="idCuentaSFDC"></param>
        /// <param name="idProyectoSFDC"></param>
        /// <param name="idOportunidadSFDC"></param>
        /// <param name="idCuentaSDFC_IdClienteFnalSFDC"></param>
        /// <param name="idServicioSFDC"></param>
        /// <returns></returns>
        public static string Insert(string idCasoSFDC, string idCaso, string tipoCaso, string motivoCaso, string problemaEncontrado, string estadoCaso, DateTime fechaHoraapertura, DateTime fechaHoraCierre, string descripcion, decimal tiempoCasoabierto, string idCuentaSFDC, string idProyectoSFDC, string idOportunidadSFDC, string idCuentaSDFC_IdClienteFnalSFDC, string idServicioSFDC)
        {
            string statusWS = PropertiesApp.StatusWS.Exitosa.ToString();
            string statusObservation = string.Empty;

            try
            {
                CASO Case = new CASO() { ID_CASOSDFC = idCasoSFDC, ID_CASO = idCaso, TIPO_CASO = tipoCaso, MOTIVO_CASO = motivoCaso, PROBLEMA_ENCONTRADO = problemaEncontrado, FECHA_HORA_APERTURA = fechaHoraapertura, FECHA_HORA_CIERRE = fechaHoraCierre, DESCRIPCION = descripcion, TIEMPO_CASO_ABIERTO = tiempoCasoabierto, ID_CUENTASFDC = idCuentaSFDC, ID_PROYECTOSFDC = idProyectoSFDC, ID_OPORTUNIDADSDFC = idOportunidadSFDC, ID_CUENTASDFC_ID_CLIENTEFINALSDFC = idCuentaSDFC_IdClienteFnalSFDC, ID_SERVICIOSDFC = idServicioSFDC, ESTADO_CASO = estadoCaso };
                Insert(Case);
            }
            catch (Exception EX)
            {
                statusWS = PropertiesApp.StatusWS.Fallida.ToString();
                statusObservation = "No se pudo insertar el Caso: " + EX.Message;
                LogErrorController.Insert(PropertiesApp.Error.OTController, EX.ToString());
            }


            XElement xmlData = new XElement("result");

            xmlData.Add(new XElement("TipoTransaccion", "CREACION CASO"),
                    new XElement("ElementoEnviado", new XElement("idCasoSFDC", idCasoSFDC),
                                                 new XElement("idCaso", idCaso),
                                                 new XElement("tipoCaso", tipoCaso),
                                                 new XElement("motivoCaso", motivoCaso),
                                                 new XElement("problemaEncontrado", problemaEncontrado),
                                                 new XElement("estadoCaso", estadoCaso),
                                                 new XElement("fechaHoraapertura", fechaHoraapertura),
                                                 new XElement("fechaHoraCierre", fechaHoraCierre),
                                                 new XElement("descripcion", descripcion),
                                                 new XElement("tiempoCasoabierto", tiempoCasoabierto),
                                                 new XElement("idCuentaSFDC", idCuentaSFDC),
                                                 new XElement("idProyectoSFDC", idProyectoSFDC),
                                                 new XElement("idOportunidadSFDC", idOportunidadSFDC),
                                                 new XElement("idCuentaSDFC_IdClienteFnalSFDC", idCuentaSDFC_IdClienteFnalSFDC),
                                                 new XElement("idServicioSFDC", idServicioSFDC)),
                    new XElement("EstadoTransaccion", statusWS),
                    new XElement("Observaciones", statusObservation),
                    new XElement("FechaTransaccion", DateTime.Now.ToString()));

            return xmlData.ToString();
               
        }

        public static string Insert(string idCasoSFDC, string idCaso, string tipoCaso, string motivoCaso, string problemaEncontrado, string estadoCaso, string fechaHoraapertura, string fechaHoraCierre, string descripcion, decimal tiempoCasoabierto, string idCuentaSFDC, string idProyectoSFDC, string idOportunidadSFDC, string idCuentaSDFC_IdClienteFnalSFDC, string idServicioSFDC, string prioridad)
        {
            string statusWS = PropertiesApp.StatusWS.Exitosa.ToString();
            string statusObservation = string.Empty;

            try
            {
                DateTime? fechaApertura = DateTime.Now;
                DateTime? fechaCierre = null;
                //if (fechaHoraapertura != "")
                //    fechaApertura = DateTime.Parse(fechaHoraapertura);

                //if (fechaHoraCierre != "")
                //    fechaCierre = DateTime.Parse(fechaHoraCierre);

                CASO Case = new CASO() { ID_CASOSDFC = idCasoSFDC, ID_CASO = idCaso, TIPO_CASO = tipoCaso, MOTIVO_CASO = motivoCaso, PROBLEMA_ENCONTRADO = problemaEncontrado, FECHA_HORA_APERTURA = fechaApertura, FECHA_HORA_CIERRE = fechaCierre, DESCRIPCION = descripcion, TIEMPO_CASO_ABIERTO = tiempoCasoabierto, ID_CUENTASFDC = idCuentaSFDC, ID_PROYECTOSFDC = idProyectoSFDC, ID_OPORTUNIDADSDFC = idOportunidadSFDC, ID_CUENTASDFC_ID_CLIENTEFINALSDFC = idCuentaSDFC_IdClienteFnalSFDC, ID_SERVICIOSDFC = idServicioSFDC, ESTADO_CASO = estadoCaso, PRIORIDAD = prioridad };
                Insert(Case);
            }
            catch (Exception EX)
            {
                statusWS = PropertiesApp.StatusWS.Fallida.ToString();
                statusObservation = "No se pudo insertar el Caso: " + EX.Message;
                LogErrorController.Insert(PropertiesApp.Error.OTController, EX.ToString());
            }


            //XElement xmlData = new XElement("result");

            //xmlData.Add(new XElement("TipoTransaccion", "CREACION CASO"),
            //        new XElement("ElementoEnviado", new XElement("idCasoSFDC", idCasoSFDC),
            //                                     new XElement("idCaso", idCaso),
            //                                     new XElement("tipoCaso", tipoCaso),
            //                                     new XElement("motivoCaso", motivoCaso),
            //                                     new XElement("problemaEncontrado", problemaEncontrado),
            //                                     new XElement("estadoCaso", estadoCaso),
            //                                     new XElement("fechaHoraapertura", fechaHoraapertura),
            //                                     new XElement("fechaHoraCierre", fechaHoraCierre),
            //                                     new XElement("descripcion", descripcion),
            //                                     new XElement("tiempoCasoabierto", tiempoCasoabierto),
            //                                     new XElement("idCuentaSFDC", idCuentaSFDC),
            //                                     new XElement("idProyectoSFDC", idProyectoSFDC),
            //                                     new XElement("idOportunidadSFDC", idOportunidadSFDC),
            //                                     new XElement("idCuentaSDFC_IdClienteFnalSFDC", idCuentaSDFC_IdClienteFnalSFDC),
            //                                     new XElement("idServicioSFDC", idServicioSFDC)),
            //        new XElement("EstadoTransaccion", statusWS),
            //        new XElement("Observaciones", statusObservation),
            //        new XElement("FechaTransaccion", DateTime.Now.ToString()));

            //return xmlData.ToString();
            return "Cadena de prueba";

        }

        /// <summary>
        /// Cierra un caso
        /// </summary>
        /// <param name="idCasosSFDC"></param>
        /// <returns></returns>
        public static void CerrarCaso(string idCasosSFDC)
        {
            CASO caso = (from c in DataContext.CASO
                         where c.ID_CASOSDFC == idCasosSFDC
                         select c).SingleOrDefault();
            caso.ESTADO_CASO = "cerrado";
            caso.FECHA_HORA_CIERRE = DateTime.Now;
            DataContext.SubmitChanges();
        }

        /// <summary>
        /// Retorna información de los casos, filtrado por cliente, proyecto o servicio
        /// </summary>
        /// <param name="id"></param>
        /// <param name="jerarquia"></param>
        /// <returns></returns>
        public static DataTable GetCaseDetail(string id, PropertiesApp.Jerarquia jerarquia, string busqueda, string idCuenta)
        {
            DataTable dt = new DataTable();
            switch (jerarquia)
            { 
                case PropertiesApp.Jerarquia.Servicio:
                    var detail = from c in DataContext.CASO
                                 join s in DataContext.SERVICIO on c.ID_SERVICIOSDFC equals s.ID_SERVICIOSDFC
                                 where c.ID_SERVICIOSDFC == id
                                 && (
                                 (busqueda == string.Empty ? true : SqlMethods.Like(c.ID_CASO, "%" + busqueda + "%"))
                                 || (busqueda == string.Empty ? true : SqlMethods.Like(c.ESTADO_CASO, "%" + busqueda + "%"))
                                 || (busqueda == string.Empty ? true : SqlMethods.Like(c.MOTIVO_CASO, "%" + busqueda + "%"))
                                 || (busqueda == string.Empty ? true : SqlMethods.Like(s.NOMBRE_SERVICIO, "%" + busqueda + "%"))
                                 )
                                 select new
                                 {
                                     id_caso = c.ID_CASOSDFC,
                                     numero_caso = c.ID_CASO,
                                     estado = c.ESTADO_CASO,
                                     fechaCierre = c.FECHA_HORA_CIERRE,
                                     fechaCierre2 = "",
                                     motivo = c.MOTIVO_CASO,
                                     enlace = s.NOMBRE_SERVICIO,
                                     fechaApertura = c.FECHA_HORA_APERTURA,
                                     fechaApertura2 = "",
                                     prioridad = c.PRIORIDAD
                                 };

                    dt = ConvertData.ToDataTable(detail);                                
                    break;
                case PropertiesApp.Jerarquia.Proyecto:
                    var detail2 = from c in DataContext.CASO
                                  join s in DataContext.SERVICIO on c.ID_SERVICIOSDFC equals s.ID_SERVICIOSDFC
                                 where c.ID_PROYECTOSFDC == id
                                 && (
                                 (busqueda == string.Empty ? true : SqlMethods.Like(c.ID_CASO, "%" + busqueda + "%"))
                                 || (busqueda == string.Empty ? true : SqlMethods.Like(c.ESTADO_CASO, "%" + busqueda + "%"))
                                 || (busqueda == string.Empty ? true : SqlMethods.Like(c.MOTIVO_CASO, "%" + busqueda + "%"))
                                 || (busqueda == string.Empty ? true : SqlMethods.Like(s.NOMBRE_SERVICIO, "%" + busqueda + "%"))
                                 )
                                 select new
                                 {
                                     id_caso = c.ID_CASOSDFC,
                                     numero_caso = c.ID_CASO,
                                     estado = c.ESTADO_CASO,
                                     fechaCierre = c.FECHA_HORA_CIERRE,
                                     fechaCierre2 = "",
                                     motivo = c.MOTIVO_CASO,
                                     enlace = s.NOMBRE_SERVICIO,
                                     fechaApertura = c.FECHA_HORA_APERTURA,
                                     fechaApertura2 = "",
                                     prioridad = c.PRIORIDAD
                                 };

                    dt = ConvertData.ToDataTable(detail2);                                

                    break;
                case PropertiesApp.Jerarquia.Cliente:
                    var detail3 = from c in DataContext.CASO
                                  join s in DataContext.SERVICIO on c.ID_SERVICIOSDFC equals s.ID_SERVICIOSDFC
                                  where c.ID_CUENTASFDC == id
                                     && (
                                     (busqueda == string.Empty ? true : SqlMethods.Like(c.ID_CASO, "%" + busqueda + "%"))
                                     || (busqueda == string.Empty ? true : SqlMethods.Like(c.ESTADO_CASO, "%" + busqueda + "%"))
                                     || (busqueda == string.Empty ? true : SqlMethods.Like(c.MOTIVO_CASO, "%" + busqueda + "%"))
                                     || (busqueda == string.Empty ? true : SqlMethods.Like(s.NOMBRE_SERVICIO, "%" + busqueda + "%"))
                                     )
                                  select new
                                  {
                                      id_caso = c.ID_CASOSDFC,
                                      numero_caso = c.ID_CASO,
                                      estado = c.ESTADO_CASO,
                                      fechaCierre = c.FECHA_HORA_CIERRE,
                                      fechaCierre2 = "",
                                      motivo = c.MOTIVO_CASO,
                                      enlace = s.NOMBRE_SERVICIO,
                                      fechaApertura = c.FECHA_HORA_APERTURA,
                                      fechaApertura2 = "",
                                      prioridad = c.PRIORIDAD
                                  };

                    dt = ConvertData.ToDataTable(detail3);

                    break;
                case PropertiesApp.Jerarquia.Todos:
                    var detail4 = from c in DataContext.CASO
                                  join s in DataContext.SERVICIO on c.ID_SERVICIOSDFC equals s.ID_SERVICIOSDFC
                                  where c.ID_CUENTASFDC.Substring(0,15) == idCuenta.Substring(0,15)
                                     && (
                                     (busqueda == string.Empty ? true : SqlMethods.Like(c.ID_CASO, "%" + busqueda + "%"))
                                     || (busqueda == string.Empty ? true : SqlMethods.Like(c.ESTADO_CASO, "%" + busqueda + "%"))
                                     || (busqueda == string.Empty ? true : SqlMethods.Like(c.MOTIVO_CASO, "%" + busqueda + "%"))
                                     || (busqueda == string.Empty ? true : SqlMethods.Like(s.NOMBRE_SERVICIO, "%" + busqueda + "%"))
                                     )
                                  select new
                                  {
                                      id_caso = c.ID_CASOSDFC,
                                      numero_caso = c.ID_CASO,
                                      estado = c.ESTADO_CASO,
                                      fechaCierre = c.FECHA_HORA_CIERRE,
                                      fechaCierre2 = "",
                                      motivo = c.MOTIVO_CASO,
                                      enlace = s.NOMBRE_SERVICIO,
                                      fechaApertura = c.FECHA_HORA_APERTURA,
                                      fechaApertura2 = "",
                                      prioridad = c.PRIORIDAD
                                  };

                    dt = ConvertData.ToDataTable(detail4);

                    break;
                default:
                    return dt;

            }

            //Se recorre la tabla de los casos para dejar en blanco las fechas con año 1753
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (dt.Rows[i]["fechaCierre"].ToString().Contains("1753"))
                    dt.Rows[i]["fechaCierre"] = DBNull.Value;                
            }


            return dt;

        }

        /// <summary>
        /// Retorna una datatable haciendo un distinct de los tipos de casos existentes en la tabla CASO
        /// </summary>
        /// <returns></returns>
        public static DataTable GetListaTipoCaso()
        {
            //IEnumerable<string> q = (from c in DataContext.CASO
            //         orderby c.TIPO_CASO
            //         select c.TIPO_CASO
            //        ).Distinct();

            //DataTable dtt = new DataTable();
            //dtt.Columns.Add("TIPO_CASO");
            //foreach (string tipo in q)
            //    dtt.Rows.Add(tipo);


            var q = from c in DataContext.TIPO_CASO
                    orderby c.TIPO_CASO1
                    select c;

            return ConvertData.ToDataTable(q);
        }

        /// <summary>
        /// Retorna una datatable haciendo un distinct de los motivos existentes en la tabla CASO
        /// </summary>
        /// <returns></returns>
        public static DataTable GetListaMotivos()
        {
            var q = (from c in DataContext.CASO
                     orderby c.MOTIVO_CASO
                     select c.MOTIVO_CASO
                    ).Distinct();

            DataTable dtt = new DataTable();
            dtt.Columns.Add("MOTIVO_CASO");
            foreach (string tipo in q)
                dtt.Rows.Add(tipo);

            return dtt;            
        }

        public static DataTable GetListaMotivosByTipoCaso(string tipoCaso)
        {
            var q = from m in DataContext.MOTIVO
                    where m.TIPO_CASO == tipoCaso
                    orderby m.MOTIVO1
                    select m;

            return ConvertData.ToDataTable(q);
        }

        /// <summary>
        /// Retorna datatable con la info de un caso y sus comentarios
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static DataSet GetCaseById(string idCasoSF)
        {
            var q = from ca in DataContext.CASO                    
                    where ca.ID_CASOSDFC == idCasoSF                    
                    select new
                    {
                        idCasoSF = ca.ID_CASOSDFC,
                        numero_caso = ca.ID_CASO,
                        tipo_caso = ca.TIPO_CASO,
                        motivo_caso = ca.MOTIVO_CASO,
                        problema_encontrado = ca.PROBLEMA_ENCONTRADO,
                        estado = ca.ESTADO_CASO,
                        fecha_apertura = ca.FECHA_HORA_APERTURA,
                        fecha_cierre = ca.FECHA_HORA_CIERRE,
                        descripcion = ca.DESCRIPCION,
                        acciones = ca.ACCIONES_CORRECTIVAS_PREVENTIVAS,
                        descripcion1 = ca.DESCRIPCION1,
                        fecha_visita = ca.FECHA_PROGRAMACION_VISITA,
                        prioridad = ca.PRIORIDAD
                    };

            var qComentarios = from co in DataContext.COMENTARIOS_CASO
                               where co.ID_CASOSDFC == idCasoSF
                               orderby co.FECHA_COMENTARIO
                               select new
                               {
                                   comentario = co.DESCRIPCION,
                                   fecha_comentario = co.FECHA_COMENTARIO,
                                   persona_comentario = co.PERSONA_REALIZA_COMENTARIO,
                                   id_comentario = co.ID_COMENTARIO,
                                   tipo_comentario = co.TIPO_COMENTARIO
                               };

            DataTable dtCaso = ConvertData.ToDataTable(q);
            DataTable dtComentarios = ConvertData.ToDataTable(qComentarios);

            //Se recorre la tabla de los casos para dejar en blanco las fechas con año 1753
            for (int i = 0; i < dtCaso.Rows.Count; i++)
            {
                if (dtCaso.Rows[i]["fecha_cierre"].ToString().Contains("1753"))
                    dtCaso.Rows[i]["fecha_cierre"] = DBNull.Value;
                if (dtCaso.Rows[i]["fecha_visita"].ToString().Contains("1753"))
                    dtCaso.Rows[i]["fecha_visita"] = DBNull.Value;
            }

            DataSet dts = new DataSet();
            dts.Tables.Add(dtCaso);
            dts.Tables.Add(dtComentarios);

            return dts;
        }

        public static string GetComentario(string idComentario)
        { 
            var q = (from c in DataContext.COMENTARIOS_CASO
                    where c.ID_COMENTARIO == idComentario
                    select c).FirstOrDefault();

            if (q == null)
                return "";
            else
                return q.DESCRIPCION;
        }


        #region "Utilizados en hme internacional"

        /// <summary>
        /// Muestra el último caso, en estado abierto, de cada cliente final del cliente en sesión. 
        /// En caso de ser un cliente final el que está en sesión, debería mostrar los casos más recientes, 
        /// en estado abierto, del usuario
        /// </summary>
        /// <param name="id">Id de la cuenta</param>
        /// <returns></returns>
        public static DataTable GetCasosRecientesByCuenta(string id)
        {
            var q = (from c in DataContext.CASO
                    join a in DataContext.CUENTA_CLIENTEFINAL on c.ID_CUENTASDFC_ID_CLIENTEFINALSDFC equals a.ID_CUENTASDFC_ID_CLIENTEFINALSDFC
                    join b in DataContext.CLIENTE_FINAL on a.ID_CLIENTEFINALSDFC equals b.ID_CLIENTEFINALSDFC
                    where c.ID_CUENTASFDC == id && (!c.ESTADO_CASO.ToUpper().Equals("CERRADO"))
                    orderby b.NOMBRE_CLIENTEFINAL, c.FECHA_HORA_APERTURA descending
                    select new
                    {
                        idCaso = c.ID_CASO,
                        idCliente = b.ID_CLIENTEFINALSDFC,
                        cliente = b.NOMBRE_CLIENTEFINAL,
                        tipo = c.TIPO_CASO,
                        fecha = c.FECHA_HORA_APERTURA
                    }).ToList();

            //Se contruye datatable de retorno
            DataTable dt = new DataTable();
            dt.Columns.Add("idCaso");
            dt.Columns.Add("idCliente");            
            dt.Columns.Add("cliente");
            dt.Columns.Add("tipo");
            dt.Columns.Add("fecha");

            //Rcorre los resutlados obtenidos y guarda solamente el primer registro de cada cliente
            string ultimoCliente = "";
            DataRow dr;
            for (int i = 0; i < q.Count; i++)
            {
                //Si cambia el cliente
                if (ultimoCliente != q[i].idCliente)
                {
                    dr = dt.NewRow();
                    dr["idCaso"] = q[i].idCaso;
                    dr["idCliente"] = q[i].idCliente;
                    dr["cliente"] = q[i].cliente;
                    dr["tipo"] = q[i].tipo;
                    dr["fecha"] = q[i].fecha;

                    dt.Rows.Add(dr);
                }

                ultimoCliente = q[i].idCliente;
            }

            //Retorna el datatable obtenido
            return dt;

        }

        /// <summary>
        /// Muestra el último caso, en estado abierto, de cada cliente final del cliente en sesión. 
        /// En caso de ser un cliente final el que está en sesión, debería mostrar los casos más recientes, 
        /// en estado abierto, del usuario
        /// </summary>
        /// <param name="id">Id del cliente final</param>
        /// <returns></returns>
        public static DataTable GetCasosRecientesByCliente(string id)
        {
            var q = (from c in DataContext.CASO
                     join a in DataContext.CUENTA_CLIENTEFINAL on c.ID_CUENTASDFC_ID_CLIENTEFINALSDFC equals a.ID_CUENTASDFC_ID_CLIENTEFINALSDFC
                     join b in DataContext.CLIENTE_FINAL on a.ID_CLIENTEFINALSDFC equals b.ID_CLIENTEFINALSDFC
                     where b.ID_CLIENTEFINALSDFC == id && (!c.ESTADO_CASO.ToUpper().Equals("CERRADO"))
                     orderby c.FECHA_HORA_APERTURA descending
                     select new
                     {
                         idCaso = c.ID_CASO,
                         idCliente = b.ID_CLIENTEFINALSDFC,
                         cliente = b.NOMBRE_CLIENTEFINAL,
                         tipo = c.TIPO_CASO,
                         fecha = c.FECHA_HORA_APERTURA
                     }).Take(5).ToList();

            //Se contruye datatable de retorno
            DataTable dt = new DataTable();
            dt.Columns.Add("idCaso");
            dt.Columns.Add("idCliente");
            dt.Columns.Add("cliente");
            dt.Columns.Add("tipo");
            dt.Columns.Add("fecha");

            //Rcorre los resutlados obtenidos y guarda solamente el primer registro de cada cliente            
            DataRow dr;
            for (int i = 0; i < q.Count; i++)
            {
                dr = dt.NewRow();
                dr["idCaso"] = q[i].idCaso;
                dr["idCliente"] = q[i].idCliente;
                dr["cliente"] = q[i].cliente;
                dr["tipo"] = q[i].tipo;
                dr["fecha"] = q[i].fecha;

                dt.Rows.Add(dr);                
            }

            //Retorna el datatable obtenido
            return dt;

        }


        /// <summary>
        /// Retorna numero de casos abiertos de una cuenta, agrupados por tipo
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static DataTable GetCasosAbiertosByTipoByCuenta(string id)
        {
            var q =  from c in DataContext.CASO
                     join a in DataContext.CUENTA_CLIENTEFINAL on c.ID_CUENTASDFC_ID_CLIENTEFINALSDFC equals a.ID_CUENTASDFC_ID_CLIENTEFINALSDFC
                     join b in DataContext.CLIENTE_FINAL on a.ID_CLIENTEFINALSDFC equals b.ID_CLIENTEFINALSDFC
                     where c.ID_CUENTASFDC == id && (!c.ESTADO_CASO.ToUpper().Equals("CERRADO"))
                     group c by new {c.TIPO_CASO} into g
                     select new
                     {
                         tipoCaso = g.Key.TIPO_CASO,
                         cantidad = g.Count()
                     };

            return ConvertData.ToDataTable(q);
        }

        /// <summary>
        /// Retorna numero de casos abiertos de un cliente, agrupados por tipo
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static DataTable GetCasosAbiertosByTipoByCliente(string id)
        {
            var q = from c in DataContext.CASO
                    join a in DataContext.CUENTA_CLIENTEFINAL on c.ID_CUENTASDFC_ID_CLIENTEFINALSDFC equals a.ID_CUENTASDFC_ID_CLIENTEFINALSDFC
                    join b in DataContext.CLIENTE_FINAL on a.ID_CLIENTEFINALSDFC equals b.ID_CLIENTEFINALSDFC
                    where b.ID_CLIENTEFINALSDFC == id && (!c.ESTADO_CASO.ToUpper().Equals("CERRADO"))
                    group c by new { c.TIPO_CASO } into g
                    select new
                    {
                        tipoCaso = g.Key.TIPO_CASO,
                        cantidad = g.Count()
                    };

            return ConvertData.ToDataTable(q);
        }

        /// <summary>
        /// Rtorna info de un caso dado su id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static DataTable GetCasoById(string id)
        {
            var q = from c in DataContext.CASO
                    join a in DataContext.CUENTA_CLIENTEFINAL on c.ID_CUENTASDFC_ID_CLIENTEFINALSDFC equals a.ID_CUENTASDFC_ID_CLIENTEFINALSDFC
                    join b in DataContext.CLIENTE_FINAL on a.ID_CLIENTEFINALSDFC equals b.ID_CLIENTEFINALSDFC
                    where c.ID_CASO == id
                    select new
                    {
                        idCaso = c.ID_CASO,
                        tipoCaso = c.TIPO_CASO,
                        motivoCaso = c.MOTIVO_CASO,
                        estado = c.ESTADO_CASO,
                        cliente = b.NOMBRE_CLIENTEFINAL
                    };

            return ConvertData.ToDataTable(q);                    
        }

        /// <summary>
        /// Retorna cantidad de casos que pertenecen determinados tipos
        /// </summary>
        /// <param name="nit"></param>
        /// <param name="tipos"></param>
        /// <returns></returns>
        public static int GetSumaCasosByTipo(string nit, string[] tipos)
        {
            var q = from c in DataContext.CASO
                    join cu in DataContext.CUENTA on c.ID_CUENTASFDC equals cu.ID_CUENTASFDC
                    where cu.NIT_CUENTA == nit && tipos.Contains(c.TIPO_CASO)
                    select c;

            return q.Count();
        }

        public static DataTable GetDetalleCasosByTipo(string nit, string[] tipos)
        {
            var q = from c in DataContext.CASO
                    join cu in DataContext.CUENTA on c.ID_CUENTASFDC equals cu.ID_CUENTASFDC
                    join se in DataContext.SERVICIO on c.ID_SERVICIOSDFC equals se.ID_SERVICIOSDFC
                    where cu.NIT_CUENTA == nit && tipos.Contains(c.TIPO_CASO)
                    orderby c.FECHA_HORA_APERTURA descending
                    select new
                    {
                        idCasoSF = c.ID_CASOSDFC,
                        idCaso = c.ID_CASO,
                        nombreServicio = se.NOMBRE_SERVICIO,
                        tipoCaso = c.TIPO_CASO,
                        estado = c.ESTADO_CASO,
                        fechaApertura = c.FECHA_HORA_APERTURA,
                        fechaApertura2 = "",
                        fechaCierre = c.FECHA_HORA_CIERRE,
                        fechaCierre2 = "",
                        motivo = c.MOTIVO_CASO
                    };

            DataTable dt = ConvertData.ToDataTable(q);

            if (dt.Rows.Count == 0)
                return dt;

            //Renombra columnas
            dt.Columns["idCaso"].ColumnName = "Número caso";
            dt.Columns["nombreServicio"].ColumnName = "Nombre Servicio";
            dt.Columns["tipoCaso"].ColumnName = "Tipo de caso";
            dt.Columns["estado"].ColumnName = "Estado";
            dt.Columns["fechaApertura2"].ColumnName = "Fecha apertura";
            dt.Columns["fechaCierre2"].ColumnName = "Fecha cierre";
            dt.Columns["motivo"].ColumnName = "Motivo";

            return dt;        
        }


        /// <summary>
        /// Retorna cantidad de casos por estado
        /// </summary>
        /// <param name="nit"></param>
        /// <param name="tipos"></param>
        /// <returns></returns>
        public static int GetSumaCasosByEstado(string nit, string[] estados)
        {
            var q = from c in DataContext.CASO
                    join cu in DataContext.CUENTA on c.ID_CUENTASFDC equals cu.ID_CUENTASFDC
                    where cu.NIT_CUENTA == nit && estados.Contains(c.ESTADO_CASO.ToUpper())
                    select c;

            return q.Count();
        }

        public static DataTable GetDetalleEstadoByEstado(string nit, string[] estados)
        {
            var q = from c in DataContext.CASO
                    join cu in DataContext.CUENTA on c.ID_CUENTASFDC equals cu.ID_CUENTASFDC
                    join se in DataContext.SERVICIO on c.ID_SERVICIOSDFC equals se.ID_SERVICIOSDFC
                    where cu.NIT_CUENTA == nit && estados.Contains(c.ESTADO_CASO.ToUpper())
                    orderby c.FECHA_HORA_APERTURA descending
                    select new
                    {
                        idCasoSF = c.ID_CASOSDFC,
                        idCaso = c.ID_CASO,
                        nombreServicio = se.NOMBRE_SERVICIO,
                        tipoCaso = c.TIPO_CASO,
                        estado = c.ESTADO_CASO,
                        fechaApertura = c.FECHA_HORA_APERTURA,
                        fechaApertura2 = "",
                        fechaCierre = c.FECHA_HORA_CIERRE,
                        fechaCierre2 = "",
                        motivo = c.MOTIVO_CASO
                    };

            DataTable dt = ConvertData.ToDataTable(q);

            if (dt.Rows.Count == 0)
                return dt;

            //Renombra columnas
            dt.Columns["idCaso"].ColumnName = "Número caso";
            dt.Columns["nombreServicio"].ColumnName = "Nombre Servicio";
            dt.Columns["tipoCaso"].ColumnName = "Tipo de caso";
            dt.Columns["estado"].ColumnName = "Estado";
            dt.Columns["fechaApertura2"].ColumnName = "Fecha apertura";
            dt.Columns["fechaCierre2"].ColumnName = "Fecha cierre";
            dt.Columns["motivo"].ColumnName = "Motivo";

            return dt;
        }


        /// <summary>
        /// Retorna numero de casos abiertos de una cuenta, agrupados por tipo
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static DataTable GetDetalleCasosAbiertosByTipoByCuenta(string id, string tipo)
        {
            var q = from c in DataContext.CASO
                    join a in DataContext.CUENTA_CLIENTEFINAL on c.ID_CUENTASDFC_ID_CLIENTEFINALSDFC equals a.ID_CUENTASDFC_ID_CLIENTEFINALSDFC
                    join b in DataContext.CLIENTE_FINAL on a.ID_CLIENTEFINALSDFC equals b.ID_CLIENTEFINALSDFC
                    where c.ID_CUENTASFDC == id && c.TIPO_CASO.Equals(tipo) && (!c.ESTADO_CASO.ToUpper().Equals("CERRADO"))                    
                    select new
                    {
                        idCasoSF = c.ID_CASOSDFC,
                        idCaso = c.ID_CASO,
                        tipoCaso = c.TIPO_CASO,
                        motivoCaso = c.MOTIVO_CASO,
                        estado = c.ESTADO_CASO,
                        cliente = b.NOMBRE_CLIENTEFINAL                                                
                    };

            return ConvertData.ToDataTable(q);
        }



        /// <summary>
        /// Retorna numero de casos abiertos de un cliente, agrupados por tipo
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static DataTable GetDetalleCasosAbiertosByTipoByCliente(string id, string tipo)
        {
            var q = from c in DataContext.CASO
                    join a in DataContext.CUENTA_CLIENTEFINAL on c.ID_CUENTASDFC_ID_CLIENTEFINALSDFC equals a.ID_CUENTASDFC_ID_CLIENTEFINALSDFC
                    join b in DataContext.CLIENTE_FINAL on a.ID_CLIENTEFINALSDFC equals b.ID_CLIENTEFINALSDFC
                    where b.ID_CLIENTEFINALSDFC == id && c.TIPO_CASO.Equals(tipo) && (!c.ESTADO_CASO.ToUpper().Equals("CERRADO"))
                    select new
                    {
                        idCasoSF = c.ID_CASOSDFC,
                        idCaso = c.ID_CASO,
                        tipoCaso = c.TIPO_CASO,
                        motivoCaso = c.MOTIVO_CASO,
                        estado = c.ESTADO_CASO,
                        cliente = b.NOMBRE_CLIENTEFINAL
                    };

            return ConvertData.ToDataTable(q);
        }

        #endregion


    }
}